self.onerror= function( exception, file, line )
{   alert( exception + ' [' + file + ':' + line + ']' );
};


new function( window ){

var $= {$: };
$.attach= arguments.callee;
$.rape= function( source ){
    for( var key in source ) this[ key ]= source[ key ];
    var hiddens= [ 'toString' ];
    for( var i= 0; i < hiddens.length; ++i ){
        var name= hiddens[ i ];
        if( source.hasOwnProperty( name ) ) this[ name ]= source[ name ];
    };
    return this;
};
$.warn= function( mesage ){
    throw message;
};

$.i=
{   raw:    'http://smileg.jino-net.ru/?iface=raw'
};

$.pair= function( key, val ){
    var klass= arguments.callee;
    if(!( this instanceof klass )) return new klass( key, val );
    this.key= key;
    this.val= val;
    return this;
};

$.prop= function( arg ){
    var klass= arguments.callee;
    if(!( this instanceof klass )) return new klass( arg );
    var get= arg.get, set= arg.set, name= arg.name || 'value';
    return function( val ){
        if( !arguments.length )
            return get ? get.call( this, val ) : arg.value;
        this[ name ]= klass(
        {   name: name
        ,   value: set ? set.call( this, val ) : val
        ,   get: get
        ,   set: set
        })
        return this;
    };
};
$.prop.define= function( obj, props ){
    for( var key in props ){
        var arg= props[ key ];
        arg.name= key;
        obj[ key ]= new this( arg );
    };
    return obj;
}

$.Klass= function( ){
    var klass= {$arg: ( this instanceof klass ) ? this.init.call( this, arg ) : new klass( arg ) };
    $.rape.call( klass, arguments.callee.prototype );
    return klass;
};
$.Klass.prototype=
{   proto: {$proto: proto ? $.rape.call( this.prototype, proto ) : void 0, this }
,   delegat: function( method ){
        var klass= this;
        return function(){
            var wrapper= new klass( this );
            return wrapper[ method ].apply( wrapper, arguments );
        };
    }
};

$.is= $.Klass().proto(
{   init       : {$val: ( this.$= val ), this }
,   defined    : {$: ( this.$ !== null )&&( this.$ !== void 0 ) }
,   nil        : {$: this.$ === null }
,   tru        : {$: ( this.$ > '' )||( this.$ < '' ) }
,   func       : {$: typeof this.$ === 'function' }
,   array      : {$: this.instance( Array ) }
,   regexp     : function(){
        try {
            if( RegExp( this.$ ) === this.$ ) return true;
        } catch( e ){ };
        return false;
    }
,   node       : {$: !!this.$.nodeName }
,   nan        : {$: isNaN( this.$ ) }
,   infinity   : {$: this.$ === ( this.$ * Infinity ) }
,   numb       : {$: ( typeof this.$ === 'number' )&&( !this.nan() ) }
,   string     : {$: typeof this.$ === 'string' }
,   bool       : {$: typeof this.$ === 'boolean' }
,   instance   : {$klass: this.defined() ? ( Object( this.$ ) instanceof klass ) : false }
,   toString   : function( ){
        var type= typeof this.$;
        switch( true ){
            case type === 'undefined'   :
            case type === 'string'      :
            case type === 'boolean'     : return type;
            case type === 'number'      : return this.nan() ? 'nan' : type;
            case this.nil()             : return 'null';
            case this.regexp()          : return 'regexp';
            case this.array()           : return 'array';
            case this.node()            : return 'node';
            default                     : return type;
        };
    }
});

$.struct= $.Klass().proto(
{   init: {$val: ( this.$= val ), this }
,   assign: {$: this.$.assign.apply( this.$, arguments ) }
,   select: {$: this.$.select.apply( this.$, arguments ) }
,   map: function( func, self ){
        return this.$.iterate(
            {$: this.struct.assign( this.key, func.call( this, this.val ) ) }
        );
    }
,   fold: function( base, func ){
        this.$.iterate(
            {$: base= func.call( this, base, this.val ) }
        );
        return base;
    }
,   every: function( func ){
        return this.fold( true,
            {$base_val: func.call( this, val ) || !( this.br= true ) }
        );
    }
,   any: function( func, self ){
        return this.fold( false,
            {$base_val: this.br= func.call( this, val ) }
        );
    }
,   count: function( ){
        return this.fold( 0, {$base: ++base } );
    }
,   keys: function( ){
        return this.fold( [],
            {$base: base.push( this.key ), base }
        );
    }
,   values: function( ){
        return this.fold( [],
            {$base_val: base.push( val ), base }
        );
    }
,   first: function( ){
        return this.fold( void 0,
            {$base_val: this.br= $.pair( this.key, val ) }
        );
    }
,   last: function( ){
        return this.fold
        (   void 0
        ,   {$base_key: key }
        ,   this
        )
    }
});

$.obj= $.Klass().proto(
{   init    : {$val: ( this.$= val ), this }
,   can     : {$iface: $.is( this.$ ).defined() && $.is( this.$[ iface ] ).func() }
,   method  : {$name: $.func( this.$[ name ] ).bind( this.$ ).$ }
,   select  : {$key: this.$[ key ] }
,   assign  : {$key_val: this.$[ key ]= val, this }
,   remove  : {$key: delete this.$[ key ], this }
,   iterate : function( func ){
        var iter= { struct: this };
        for( var key in this.$ ){
            iter.key= key;
            iter.val= this.select( key );
            func.call( iter );
            if( iter.br ) break;
        };
        return this;
    }
,   map     : $.struct.delegat( 'map' )
,   fold    : $.struct.delegat( 'fold' )
,   every   : $.struct.delegat( 'every' )
,   any     : $.struct.delegat( 'any' )
,   count   : $.struct.delegat( 'count' )
,   first   : $.struct.delegat( 'first' )
,   last    : $.struct.delegat( 'last' )
,   keys    : $.struct.delegat( 'keys' )
,   values  : $.struct.delegat( 'values' )
});

$.hash= $.Klass().proto(
{   init    : {$vals:
        this.data= $.list( vals ).fold( $.obj({}), {$base_key:
            base.assign( '#' +  this.select( key ), true );
        });
    }
,   can     : $.obj.delegat( 'can' )
,   method  : $.obj.delegat( 'method' )
,   select  : {$key: this.data.select( '#' +  key ) }
,   assign  : {$key_val: this.data.assign( '#' +  key, val ), this }
,   iterate : {$func: this.data.iterate({$key: func.call( this, this.select( 'key' ) ) }), this }
,   map     : $.struct.delegat( 'map' )
,   fold    : $.struct.delegat( 'fold' )
,   every   : $.struct.delegat( 'every' )
,   any     : $.struct.delegat( 'any' )
,   count   : $.struct.delegat( 'count' )
,   first   : $.struct.delegat( 'first' )
,   last    : $.struct.delegat( 'last' )
});

$.func= $.Klass().proto(
{   init    : {$val: ( this.$= val ), this }
,   bind    : {$obj: {$func: $.func( {$: func.apply( obj, arguments ) } ) }( this.$ ) }
,   can     : $.obj.delegat( 'can' )
,   method  : $.obj.delegat( 'method' )
});

$.list= $.Klass().proto(
{   init    : {$val: ( this.$= val ), this }
,   select  : {$key: this.$[ key ] }
,   assign  : {$key_val: ( this.$[ key ]= val ), this }
,   iterate : function( func ){
        var br= {$: delete br };
        for( var key= 0, length= this.count(); ( key < length ) && br; ++key )
            func.call( this, key, br );
        return this;
    }
,   count   : {$: this.$.length }
,   first   : {$: this.$[0] }
,   last    : {$: this.$[ this.count() - 1 ] }
});

new function(){
    var scripts= document.getElementsByTagName( 'script' );
    var $tp= $.touchPoint= scripts[ scripts.length - 1 ];
    eval( $tp.innerHTML );
};


}( self );
